package com.bestcem.xm.member.grpc.service;

import com.bestcem.bp.grpc.v1.base.BaseTime;
import com.bestcem.bp.grpc.v1.base.Page;
import com.bestcem.xm.common.core.domain.web.RpcStatusResult;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.uitls.GRpcUtil;
import com.bestcem.xm.member.grpc.service.param.ListSourceCardsParam;
import com.bestcem.xm.member.grpc.service.param.PageParam;
import com.bestcem.xm.member.grpc.v1.services.ListSourceCardsRequest;
import com.bestcem.xm.member.grpc.v1.services.ListSourceCardsResponse;
import com.bestcem.xm.member.grpc.v1.services.SourceCard;
import com.bestcem.xm.member.grpc.v1.services.SourceCardServiceGrpc;
import com.bestcem.xm.member.service.SourceCardService;
import com.bestcem.xm.member.service.dto.PageDTO;
import com.bestcem.xm.member.service.dto.SourceCardDTO;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.validation.ConstraintViolation;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author ming.xue <ming.xue@idiaoyan.com>
 * @desc 来源名片服务
 * @date 2021-08-01
 */
@GrpcService
public class SourceCardGrpcService extends SourceCardServiceGrpc.SourceCardServiceImplBase {
    /**
     * 来源名片服务
     */
    @Autowired
    private SourceCardService sourceCardService;

    /**
     * 分页获取联系人来源名片
     *
     * @param request
     * @param responseObserver
     */
    @Override
    public void listSourceCards(ListSourceCardsRequest request,
                                StreamObserver<ListSourceCardsResponse> responseObserver) {
        ListSourceCardsResponse.Builder builder = ListSourceCardsResponse.newBuilder();

        // 参数转换
        ListSourceCardsParam param = new ListSourceCardsParam();
        if (request.hasPage()) {
            Page page = request.getPage();
            param.setPage(new PageParam(page.getPage(), page.getSize()));
        }
        param.setOrgId(request.getOrgId());
        param.setMemberId(request.getMemberId());

        // 参数校验
        Set<ConstraintViolation<Object>> violations = GRpcUtil.validateParam(param);
        if (!CollectionUtils.isEmpty(violations)) {
            ConstraintViolation<Object> violation = violations.iterator().next();
            builder.setStatus(RpcStatusResult.error(violation.getMessage()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 获取来源名片列表
        ServiceResult<PageDTO<SourceCardDTO>> result = sourceCardService.listSourceCards(param);
        if (!result.isSuccess()) {
            builder.setStatus(RpcStatusResult.error(result.getMsg()));
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();
            return;
        }

        // 处理返回结果
        PageDTO<SourceCardDTO> pageDTO = result.getData();
        List<SourceCard> sourceCards = this.toSourceCards(pageDTO.getRows());
        responseObserver.onNext(builder.setStatus(RpcStatusResult.success()).setTotal(pageDTO.getTotal())
                .addAllCards(sourceCards).build());
        responseObserver.onCompleted();
    }

    /**
     * 类型转换
     *
     * @param sourceCardDTOs
     * @return
     */
    private List<SourceCard> toSourceCards(List<SourceCardDTO> sourceCardDTOs) {
        if (CollectionUtils.isEmpty(sourceCardDTOs)) {
            return Collections.emptyList();
        }

        return sourceCardDTOs.stream().map(this::toSourceCard)
                .collect(Collectors.toList());
    }

    /**
     * 类型转换
     *
     * @param sourceCardDTO
     * @return
     */
    private SourceCard toSourceCard(SourceCardDTO sourceCardDTO) {
        SourceCard.Builder builder = SourceCard.newBuilder();
        if (sourceCardDTO == null) {
            return builder.build();
        }
        GRpcUtil.fillDefaultValue(sourceCardDTO);

        BaseTime baseTime = BaseTime.newBuilder()
                .setCreateTime(GRpcUtil.getTimestamp(sourceCardDTO.getCreateTime()))
                .setUpdateTime(GRpcUtil.getTimestamp(sourceCardDTO.getUpdateTime()))
                .build();
        return builder.setNo(sourceCardDTO.getNo()).setSourceValue(sourceCardDTO.getSource())
                .setName(sourceCardDTO.getName()).setGender(sourceCardDTO.getGender())
                .setAppId(sourceCardDTO.getAppId()).setOpenId(sourceCardDTO.getOpenId())
                .setAlipayUserId(sourceCardDTO.getAlipayUserId()).setMobile(sourceCardDTO.getMobile())
                .setEmail(sourceCardDTO.getEmail())
                .setBase(baseTime)
                .build();
    }
}
